package com.sz.app.customer.api.logistics;

import com.sz.biz.app.web.BaseController;
import com.sz.biz.common.constants.CommCodes;
import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.MessagesCodes;
import com.sz.biz.common.customer.entity.CusUser;
import com.sz.biz.common.customer.service.CustomerUserService;
import com.sz.biz.common.utils.OrderMake;
import com.sz.biz.logistics.ord.constants.OrderConstants;
import com.sz.biz.logistics.ord.dto.OrdOrderDto;
import com.sz.biz.logistics.ord.dto.OrdOrderServiceInfoDto;
import com.sz.biz.logistics.ord.entity.OrdOrder;
import com.sz.biz.logistics.ord.entity.OrderDetail;
import com.sz.biz.logistics.ord.entity.OrderStatus;
import com.sz.biz.logistics.ord.service.OrdOrderService;
import com.sz.common.base.dto.CommonModel;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.BizException;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.utils.DateUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalUtils;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.List;

/**
 * Function: 订单controller
 * Author: yanhong.xiao.<br>
 * Date: 2017-05-16 16:08:00.
 */
@RestController
@RequestMapping("/api/v1/order/orders")
@Api(description = " ", tags = "037-001、订单")
public class OrdOrderController extends BaseController {
    @Autowired
    private OrdOrderService service;
    @Autowired
    private CustomerUserService cusUserService;

    /**
     * 下单
     */
    @ApiOperation(value = "新增", notes = "新增产品订单<br>权限：", position = 1)
    @RequestMapping(value = "", method = {RequestMethod.POST})
    public ResultDto save(@RequestBody @ApiParam(value = "要保存的数据", required = true) @Validated OrdOrderDto dto) {
        dto.setId(null);//保存时忽略id
        dto.setType(OrderConstants.OrderPlatform.ORDER_CUSTOMER);//客户系统的订单
        String orderNo = service.saveOrderDto(dto);
        OrdOrder ordOrder = service.findByOrderNo(orderNo);
        String messagesCode = MessagesCodes.MODULE_ORDER_PRODUCT;
        if (dto.getOrderStatus() == OrderStatus.DRAFT) {
            messagesCode = MessagesCodes.MODULE_ORDER_PRODUCT_DRAFT;
        } else if (dto.getOrderStatus() == OrderStatus.COMMITED) {
            messagesCode = MessagesCodes.MODULE_ORDER_PRODUCT_COMMITED;
        }
        ResultDto result = getOperateSuccessDto(messagesCode);

        String[] resultData = new String[2];
        resultData[0] = ordOrder.getWaybillNo();
        //处理客户地址的保存
        this.saveCusAddress(dto, resultData);
        result.setData(resultData);
        return result;
    }

    /**
     * 修改，只有草稿状态的订单才可以进行修改
     */
    @RequestMapping(value = "{orderNo}", method = {RequestMethod.POST})
    @ApiOperation(value = "修改", notes = "修改产品订单数据<br>权限：", position = 2)
    public ResultDto update(@RequestBody @Validated OrdOrderDto dto) {
        //判断订单编号不为空
        if (org.apache.commons.lang3.StringUtils.isEmpty(dto.getOrderNo())) {
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON, "订单号不能为空");
        }
        service.updateByDto(dto, CommCodes.CUSTOMER);
        String messagesCode = MessagesCodes.MODULE_ORDER_PRODUCT;
        ResultDto result;
        switch (dto.getOrderStatus()) {
            case DRAFT:
                messagesCode = MessagesCodes.MODULE_ORDER_PRODUCT_DRAFT;
                result = getOperateSuccessDto(messagesCode);
                break;
            case COMMITED:
                messagesCode = MessagesCodes.MODULE_ORDER_PRODUCT_COMMITED;
                result = getOperateSuccessDto(messagesCode);
                break;
            default:
                result = getUpdateSuccessDto(messagesCode);
                break;
        }
       OrdOrder ordOrder =  service.findByOrderNo(dto.getOrderNo());
        String[] resultData = new String[2];
        resultData[0] = ordOrder.getWaybillNo();
        //处理客户地址的保存
        this.saveCusAddress(dto, resultData);
        result.setData(resultData);
        return result;
    }

    private void saveCusAddress(OrdOrderDto dto, String[] resultData) {
        try {
            service.saveCusUserAddress(dto);
        } catch (Exception e) {
            if (e instanceof BizException) {
                BizException exception = (BizException) e;
                resultData[1] = String.valueOf(exception.getErrorCode());
            }
            logger.error("客户地址保存失败", e);
        }
    }


    /**
     * 根据orderNo查询订单详情
     *
     * @param orderNo 产品订单的orderNo
     * @return 查询到的单条产品订单
     */
    @RequestMapping(value = "/{orderNo}", method = RequestMethod.GET)
    @ApiOperation(value = "根据orderNo查询订单详情", notes = "根据orderNo查询订单详情", position = 3)
    public ResultDto findByOrderNo(@ApiParam(value = "产品订单orderNo", required = true) @PathVariable String orderNo) {
        OrdOrderDto orderDto = service.findDtoByOrderNo(orderNo);
        ResultDto result = new ResultDto();
        result.setData(orderDto);
        return result;
    }

    /**
     * 根据条件获取数据集合
     *
     * @param q         参数信息
     * @param pageIndex 哪页
     * @param pageSize  分页大小
     * @param orderNo   订单编号
     * @param sort      排序字段的名称
     * @param asc       true asc false desc
     * @return 查询的数据集合
     */
    @ApiOperation(value = "列表搜索", notes = "根据指定条件获取数据集合")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "模糊查询参数", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", dataType = "int", paramType = "query", defaultValue
                    = "1"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数,max<2000", dataType = "int", paramType = "query",
                    defaultValue = "10"),
            @ApiImplicitParam(name = "sort", value = "排序的字段", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orderNo", value = "订单编号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "cusOrderNo", value = "客户单号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "asc", value = "排序方式", dataType = "boolean", paramType = "query", defaultValue =
                    "true"),
            @ApiImplicitParam(name = "startEffectTime", value = "开始时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "endEffectTime", value = "结束时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orderStatus", value = "订单状态", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "productUid", value = "产品uid", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "cusUserId", value = "账号id", dataType = "int", paramType = "query")
    })
    @RequestMapping(value = "", method = RequestMethod.GET)
    public ResultDto find(@RequestParam(required = false) String q,
                          @RequestParam(required = false, defaultValue = "1") int pageIndex,
                          @RequestParam(required = false, defaultValue = "10") int pageSize,
                          @RequestParam(required = false) String orderNo,
                          @RequestParam(required = false) String cusOrderNo,
                          @RequestParam(required = false, defaultValue = "") String startEffectTime,
                          @RequestParam(required = false, defaultValue = "") String endEffectTime,
                          @RequestParam(required = false) OrderStatus orderStatus,
                          @RequestParam(required = false) String productUid,
                          @RequestParam(required = false, defaultValue = "0") int cusUserId,
                          @RequestParam(required = false) String sort,
                          @RequestParam(required = false, defaultValue = "true") Boolean asc
    ) {
        q = StringUtils.replaceSqlPattern(q);
        QueryParams qp = new QueryParams(pageSize, pageIndex, q, sort, asc);
        try {
            //状态，默认条件
            if (!ObjectUtils.isEmpty(orderStatus)) {
                qp.put("orderStatus", orderStatus);
            }
            //主账号和子账号的处理,默认条件
            int loginUserId = PrincipalUtils.getAccountId();
            CusUser loginCusUser = cusUserService.findById(loginUserId);
            if (ObjectUtils.isEmpty(loginCusUser)) {
                return new ResultDto();
            }
            int userId = loginCusUser.getId();
            if (cusUserId > 0 && cusUserId != loginUserId) {
                CusUser searchCusUser = cusUserService.findById(cusUserId);
                if (!ObjectUtils.isEmpty(searchCusUser)) {
                    if (searchCusUser.getRefCustomerId().equals(loginCusUser.getRefCustomerId())) {
                        userId = cusUserId;
                    }
                } else {
                    cusUserId = loginUserId;
                }
            }
            qp.put("customerId", loginCusUser.getRefCustomerId());
            if (loginCusUser.getIsSystem() && userId == cusUserId) {
                qp.put("cusUserId", cusUserId);
            } else if (!loginCusUser.getIsSystem()) {
                qp.put("cusUserId", loginUserId);
            }

            //主单号具有搜索优先级
            if (!ObjectUtils.isEmpty(orderNo)) {//客户系统传的是运单号
                qp.put("waybillNo", orderNo.trim());
            } else {
                if (!ObjectUtils.isEmpty(cusOrderNo)) {
                    qp.put("externalNo", cusOrderNo.trim());
                } else {
                    //产品信息
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(productUid)) {
                        qp.put("productUid", productUid.trim());
                    }
                    try {
                        if (!ObjectUtils.isEmpty(startEffectTime)) {
                            qp.put("startEffectTime", DateUtils.convertToDate(startEffectTime, DateUtils.FORMAT_DETAIL));
                        }
                        if (!ObjectUtils.isEmpty(endEffectTime)) {
                            qp.put("endEffectTime", DateUtils.convertToDate(endEffectTime, DateUtils.FORMAT_DETAIL));
                        }
                    } catch (ParseException e) {
                        throw Exceptions.bizException(com.sz.biz.logistics.constants.ErrorCodes.ERROR_ARGUMENT_ILLEGAL, "startEffectTime or endEffectTime ");
                    }
                }
            }

        } catch (Exception e) {
            logger.error("客户订单查询异常！", e);
        }
        ResultDto result = service.findDtoByParam(qp);
        return result;
    }


    /**
     * 批量删除
     *
     * @param ids 要删除的id集合
     * @return 操作结果
     */
    @ApiOperation(value = "删除", notes = "根据指定orderNo集合删除数据<br>", httpMethod = "POST", position = 5)
    @RequestMapping(value = "/deletions", method = {RequestMethod.POST})
    public ResultDto batchDelete(@RequestBody @ApiParam(value = "要删除的orderNo集合", required = true) List<String> ids) {
        service.batchDeleteByOrderNos(ids);
        ResultDto dto = getDeleteSuccessDto(MessagesCodes.MODULE_ORDER_PRODUCT);
        return dto;
    }

    @ApiOperation(value = "客户获取客户订单号", notes = "客户获取客户订单号<br>", httpMethod = "GET", position = 6)
    @RequestMapping(value = "/cusOrderNo", method = {RequestMethod.GET})
    public ResultDto getExternalNo() {
        int userId = PrincipalUtils.getAccountId();
        if (userId == 0) {
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON, "账户登录异常");
        } else {
            String cusOrderNo = OrderMake.generateCusExternalNo();
            ResultDto result = new ResultDto();
            result.setData(cusOrderNo);
            return result;
        }
    }

    @ApiOperation(value = "检查客户填写的客户订单号是否已经存在", notes = "检查客户填写的客户订单号是否已经存在<br>", httpMethod = "POST", position = 7)
    @RequestMapping(value = "/cusOrderNo/{externalNo}/{id}", method = {RequestMethod.POST})
    public ResultDto checkExternalNo(@ApiParam(required = true) @PathVariable String externalNo, @PathVariable int id) {
        ResultDto result = new ResultDto();
        if (org.apache.commons.lang3.StringUtils.isBlank(externalNo)) {
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON, "参数不能为空");
        }
        int userId = PrincipalUtils.getAccountId();
        if (userId == 0) {
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON, "账户登录异常");
        } else {
            CusUser cusUser = cusUserService.findById(userId);
            if (cusUser == null) {
                //账号不存在
                throw Exceptions.bizException(ErrorCodes.ERROR_COMMON, "账号异常");
            }
            OrdOrder ordOrder = service.findByExternalNoAndCustomerId(externalNo, cusUser.getRefCustomerId(), id);
            if (!ObjectUtils.isEmpty(ordOrder)) {
                result.setData(ordOrder);
            }
        }
        return result;
    }

    @ApiOperation(value = "批量获取订单详情", notes = "根据指定orderNo集合批量获取订单详情<br>", httpMethod = "POST", position = 9)
    @RequestMapping(value = "/details", method = {RequestMethod.POST})
    public ResultDto batchGetDetails(@RequestBody @ApiParam(value = "要获取详情的orderNo集合", required = true) List<String> orderNos) {
        List<OrdOrderDto> resultDtos = service.findDtosByOrderNos(orderNos);
        ResultDto dto = new ResultDto();
        dto.setData(resultDtos);
        return dto;
    }

    /**
     * 获取所有订单的状态数据
     *
     * @return
     */
    @RequestMapping(value = "/orderstatus", method = RequestMethod.GET)
    @ApiOperation(value = "获取所有订单的状态数据", notes = "获取订单的所有状态数据", position = 10)
    public ResultDto getAllOrderStatus() {
        List<CommonModel> list = service.getAllOrderStatus();
        ResultDto result = new ResultDto();
        result.setData(list);
        return result;
    }


    /**
     * 根据订单号获取订单服务信息
     *
     * @param orderNo 订单的orderNo
     * @return 订单服务信息
     */
    @RequestMapping(value = "/order/serviceinfo/{orderNo}", method = RequestMethod.GET)
    @ApiOperation(value = "根据订单号获取订单服务信息_orderNo", notes = "根据orderNo获取到的订单", position = 5)
    public ResultDto findOrderServiceInfo(@ApiParam(value = "订单orderNo", required = true) @PathVariable String orderNo) {
        List<OrdOrderServiceInfoDto> infoDtoList = service.findOrderServiceInfo(orderNo, true);
        ResultDto result = new ResultDto();
        result.setData(infoDtoList);
        return result;
    }


    @ApiOperation(value = "获取已受理的最新10条订单", notes = "获取已受理的最新10条订单<br>", httpMethod = "GET", position = 11)
    @RequestMapping(value = "/neworders", method = {RequestMethod.GET})
    public ResultDto getOrders() {
            List<OrderDetail> orderDetails = service.getOrders();
            ResultDto result = new ResultDto();
            result.setData(orderDetails);
            return result;
    }
}
